feat(dialog): add default_suffix to the save-file picker#138
Merged
pabloinigoblasco merged 2 commits intoJun 29, 2026
Conversation
Add WidgetData::setSaveFilePicker and the matching WidgetDataView accessors so a plugin can turn a button into a native "save as" chooser. The chosen path is delivered through the existing onFileSelected handler, so no new event type or typed handler is required. This is a backward-compatible API addition, so bump the SDK to 0.13.0 and bring recipe.yaml back in sync with the other version sources. Contents: - setSaveFilePicker(name, text, filter, title, default_suffix) -> "save_file_picker" action - WidgetDataView: isSaveFilePicker / saveFilePickerFilter / Title / DefaultSuffix - version 0.13.0 in conanfile.py, CMakeLists.txt, recipe.yaml + docstring example - docs: dialog-sdk-reference.md and dialog-plugin-guide.md
The save-file picker now lives on top of the markers/data-processors unification branch. setSaveFilePicker / isSaveFilePicker are taken from that branch; this branch's only remaining contribution is the optional default_suffix argument (and its saveFilePickerDefaultSuffix accessor), appended to the typed name when it carries no extension. Filter/title are read through the shared filePicker accessors, matching that branch's style.
Alvvalencia
added a commit
that referenced
this pull request
Jun 29, 2026
…ta_processors.v1 (kind discriminator) (#135) * Add PlotMarkers canonical builtin object + codec (markers Phase 1) New SDK builtin type for time-series plot markers (findings), the foundation of the anomaly-detection pipeline feature. - PlotMarkers (kPlotMarkers = 18): homogeneous, id-less marker records (Region / Event / ValueBand / Label) with shared semantic fields (status, severity, category, label, description, color, metadata) + a PlotMarkers list container. No id/source/scope by design — identity is owned by the host marker store; location carries provenance/reach. - Hand-written PJ.PlotMarkers wire codec following the image_annotations_codec idiom; PlotMarkers.proto contract. - Registered in C++ + C-ABI builtin enums, name()/parse()/typeOf(), and the ABI layout sentinel (static_assert id == 18). - Round-trip codec tests; full pj_base suite green (32/32) under ASAN. - Design (use-cases, architecture) + wire-format docs. ColorRGBA reused via image_annotations.hpp per the existing house convention (mesh3d / scene_entities do the same). abi/baseline.abi refresh + SDK MINOR version bump deferred to the release-cut step (additions-only). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add pj.marker_store.v1 C-ABI service (create/delete/query markers) The plugin-facing contract for plot markers, mirroring the object read/write host pattern. - C vtable PJ_marker_store_host_vtable_t + fat pointer + an owning PJ_marker_query_handle_t (plugin_data_api.h): add / remove / query / query_bytes / release_query. Markers cross as serialized PJ.PlotMarkers bytes; ids cross as uint64. - C++ MarkerStoreHostView (plugin_data_api.hpp) wrapping the codec so callers work in typed sdk::PlotMarker; add(single|batch) -> ids, remove(id), query -> [{id, marker}]. + MarkerEntry. - MarkerStoreService trait (service_traits.hpp), "pj.marker_store.v1". ABI is additive (new service); abi/baseline.abi refresh deferred to the release-cut step. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * markers: drop pj.marker_store.v1 service; add object-on-dataset toolbox slot Markers become a builtin object published to the ObjectStore via the generic object-write surface; the producer republishes the whole PlotMarkers set (last-writer-publish). The dedicated pj.marker_store.v1 service (vtable, MarkerStoreHostView, service trait) is removed. Add a tail-appended, idempotent toolbox-host slot register_object_topic_on_dataset(DatasetId, ...) so a toolbox can annotate an existing dataset (the object-write path was previously source-scoped). Add marker object-topic naming helpers (markerObjectTopicName / kGlobalMarkerTopic) to plot_markers.hpp. Update the ABI layout sentinel (88->96) and the two mock vtables. The PlotMarkers type + codec are unchanged. Docs (plot_markers_*) updated to the ObjectStore + republish model. MINOR bump + abi/baseline.abi refresh deferred to release. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * markers: MarkerTimeline dialog widget + dataset-scoped read & object-retention toolbox ABI slots Dialog protocol: add the MarkerTimeline custom widget (TimelineMark setters/event/parser/callback) for an editable multi-marker strip, with a single shared TimelineMark<->JSON codec used by all four sites. Toolbox host ABI (tail-appended, struct_size-gated): lookup_topic_on_dataset on the object-read vtable (dataset-scoped topic resolution; the name-only lookup is ambiguous across datasets) and set_object_topic_retention on the write vtable (keep-latest-N so a republishing producer's snapshots don't accumulate). Toolbox-host vtable 96->104; sentinels + mock vtables updated. Add sdk::markerSeriesKey (single-slash join tolerating a leading-'/' field) so producer and overlay build the per-series key identically. Doc refresh. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(dialog): save-as file picker + chart-marker overlay; codec cleanup Additive dialog-protocol surface (ABI-safe, no version bump): - setSaveFilePicker / isSaveFilePicker — a native "Save As" picker (getSaveFileName) so a not-yet-existing file can be created; reported via the existing onFileSelected. - ChartMarker + setChartMarkers / chartMarkers — overlay markers (events/regions/ value-bands) on a chart preview, alongside setChartSeries. - Fix a stale comment that referenced QLineSeries (the preview is Qwt, not Qt Charts). Cleanup: decodeMarker now drives the shared builtin_wire::parseFields loop like the sibling codecs, replacing the hand-rolled continue/break/skip control flow. Behavior and wire format are unchanged (codec round-trip tests pass). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RcygzPWUrHf9jHGGwzEzZo * chore(sdk): bump to 0.12.0 (PlotMarkers builtin on top of merged 0.11.0) Adding the PlotMarkers canonical builtin (slot 19) is a MINOR addition over main's 0.11.0, so the merged SDK is a distinct 0.12.0 — not the upstream 0.11.0 (which lacks PlotMarkers). Keeps version identity clean for downstream pins. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BeoYQHmF6ixvYv9KXXgyVh * feat(pj_base): add pj.markers.v1 host service (whole-series markers + ephemeral preview) The whole-series analog of pj.data_processors.v1: a plugin submits a marker generator by data (script + input series + an output marker-topic + params) and the HOST runs it over the whole series and publishes the resulting PlotMarkers to the ObjectStore. Nothing executable crosses the boundary. - PJ_markers_host_vtable_t (plugin_data_api.h): create/remove/list/config + tail-appended set_marker_preview / clear_marker_preview for a live, ephemeral (non-persisted) preview generator read back through the object surface. - MarkersHostView (sdk/plugin_data_api.hpp) + MarkersHostService trait. - params_json {"scope":"all"} makes a global generator publish across every dataset; absent = the active dataset only. - markers_api_test.cpp: fake-host ABI test (forwarding, count-then-fill, borrowed-string lifetime, binary-safe payload, preview slots). Single output_marker_topic (not an outputs[] array): a generator writes exactly one marker topic (global or per-series). NOTE: MINOR version bump (conanfile.py / PJ_PACKAGE_VERSION / recipe.yaml) and the abidiff baseline refresh are pending pre-merge — this commit adds API on a feature branch (WIP) and does not bump the release version yet. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsY1SE2yBsX2qXvkgEnX8U * feat(sdk)!: replace pj.markers.v1 with unified pj.generators.v1 service Unify the whole-series host-driven service under one SDK contract, PJ_generators_host_vtable_t / GeneratorsHostService ("pj.generators.v1"), with a string `kind` discriminator: - kind="markers" (objects -> ObjectStore) is implemented; shared `language` param, compile-only validate_script, ephemeral-preview flag, and out_topics return apply across kinds. - kind="transform" (per-sample timeseries -> DerivedEngine) is RESERVED, not implemented; its end-state home is decided when the transform-editor work merges. Removes PJ_markers_host_vtable_t / MarkersHostService (the old pj.markers.v1) and markers_api_test; adds generators_api_test. A speculative kind="field" that briefly existed on this branch was dropped (zero consumers, violated the object/timeseries engine split); it changed no ABI struct since `kind` is a runtime string. Versioning: API removal, normally MAJOR. Ships as 0.13.0 because no public tag ever carried pj.markers.v1 (no released plugin breaks). The first public release carrying pj.generators.v1 MUST be tagged 1.0.0 -- recorded in CHANGELOG.md + a comment by `version` in conanfile.py. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013N1nzqco4Y9AQhnQgXo5tQ * style(sdk): clang-format the unified data-processors API surface Applies the pre-commit clang-format pass that the merge commit (bf7eb0f) skipped via --no-verify. Formatting only — no semantic change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FHPK8VduUcoenjL8AtoSVd * style(sdk): clang-format remaining branch files (proto + dialog typed) Completes the formatting pass over the full PR diff (PlotMarkers.proto column alignment + dialog_plugin_typed.hpp signature wrap) that the narrowly-scoped previous pass missed. Formatting only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FHPK8VduUcoenjL8AtoSVd * feat(dialog): add save-file picker to the dialog SDK (#138) Add WidgetData::setSaveFilePicker and the matching WidgetDataView accessors so a plugin can turn a button into a native "save as" chooser. The chosen path is delivered through the existing onFileSelected handler, so no new event type or typed handler is required. This is a backward-compatible API addition, so bump the SDK to 0.13.0 and bring recipe.yaml back in sync with the other version sources. Contents: - setSaveFilePicker(name, text, filter, title, default_suffix) -> "save_file_picker" action - WidgetDataView: isSaveFilePicker / saveFilePickerFilter / Title / DefaultSuffix - version 0.13.0 in conanfile.py, CMakeLists.txt, recipe.yaml + docstring example - docs: dialog-sdk-reference.md and dialog-plugin-guide.md --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Pablo Iñigo Blasco <pablo.inigo@ibrobotics.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Builds on
PlotJuggler/plotjuggler_sdk#135(which introduces the save-file picker as part of thepj.data_processors.v1unification) and adds the optionaldefault_suffixargument tosetSaveFilePicker— appended to the typed filename when it carries no extension (so exportinglibrarysaveslibrary.json).Targeted at
feature/plot-markersso the two merge cleanly: the picker's setter andisSaveFilePickerare identical to #135's; this branch's only delta isdefault_suffixplus itssaveFilePickerDefaultSuffixaccessor. Filter/title are read through the sharedfilePicker*accessors, matching #135's style.Contents
WidgetData::setSaveFilePickergainsdefault_suffix = ""(writese["default_suffix"]).WidgetDataView::saveFilePickerDefaultSuffix.dialog-sdk-reference.md,dialog-plugin-guide.md.Pairs with
The host rendering (
PlotJuggler/PJ4#252) and the Transform Editor library Export that uses it (PlotJuggler/pj-official-plugins#158).